﻿using PetkaWebDav.Server.Framework;
using PetkaWebDav.Server.Framework.Security;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Routing;

namespace CloudStorageLight.Core.WebDav
{
    public abstract class AzureBlobWebDavHandlerBase : HttpTaskAsyncHandler  
    {
        private WebDavProcessor webDavProcessor 
        {
            get
            {
                __webDavProcessor = new WebDavProcessor(Settings.Authentication);
                return __webDavProcessor;
            }
        }
        private WebDavProcessor __webDavProcessor;

        public AzureBlobWebDavHandlerBase()
        {
                
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        protected abstract BlobServiceBase CreateBlobService();

        protected virtual BlobUser GetCurrentUser()
        {
            return new BlobUser(System.Web.HttpContext.Current.User);
        }
        public override async System.Threading.Tasks.Task ProcessRequestAsync(HttpContext context)
        {
            var _retValue = string.Concat(context.Request.Url.Segments);
            if (_retValue.StartsWith(Settings.WebDavPrefix)) _retValue = _retValue.Substring(Settings.WebDavPrefix.Length);
            var path = "/" + BlobUtil.UnescapeDataString(_retValue);
            var userId = System.Web.HttpContext.Current.User.Identity.Name;

            Debug.WriteLine("******** AzureBlobWebDavHandler " + context.Request.HttpMethod  + "" + path + "  " + userId);
            try
            {
                context.Response.StatusCode = 200;
                using(var svc = CreateBlobService())
                {
                    var user = GetCurrentUser();

                    context.Items["__BlobService__"] = svc;
                    context.Items["__BlobUser__"] = user;

                    var canAccess = await svc.CanModifyAsync(user, path) && await svc.CanReadAsync(user, path);
                    if (!canAccess)
                    {
                        context.Response.StatusCode = 403;
                        context.Response.End();
                    }
                    if (context.Request.HttpMethod == "PUT" || context.Request.HttpMethod == "LOCK" || context.Request.HttpMethod == "DELETE")
                    {
                        var file = (BlobFile)await svc.GetBlobItemAsync(user, path);
                        if (file.IsCheckOut && file.CheckOutUserId != userId)
                        {
                            context.Response.StatusCode = 423;
                            context.Response.End();
                        }
                    }
                    if (context.Response.StatusCode == 200)
                    {
                        try
                        {
                            await webDavProcessor.ProcessRequest(context.ApplicationInstance);

                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.ToString());
                            throw;
                        }
                    }

                }
            }
            finally
            {
                Debug.WriteLine("******** AzureBlobWebDavHandler complete:" + context.Response.Status);
            }
        }

    }
}